package pers.youqu.item.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cglib.core.EmitUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import pers.youqu.common.constants.MQConstants;
import pers.youqu.common.dto.BaseDTO;
import pers.youqu.common.dto.PageDTO;
import pers.youqu.common.exception.YqException;
import pers.youqu.common.utils.EmptyUtil;
import pers.youqu.common.utils.JsonUtils;
import pers.youqu.item.dto.SkuDTO;
import pers.youqu.item.dto.SpecParamDTO;
import pers.youqu.item.dto.SpuDTO;
import pers.youqu.item.dto.SpuDetailDTO;
import pers.youqu.item.mapper.SpuMapper;
import pers.youqu.item.po.*;
import pers.youqu.item.service.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Jason
 * @version 1.0.0
 * @date 2020/12/7 16:08
 * @Description TODO
 */
@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements SpuService {

    @Autowired
    private SpecParamService specParamService;
    @Autowired
    private SpuDetailService spuDetailService;
    @Autowired
    private BrandService brandService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SkuService skuService;
    @Autowired
    private AmqpTemplate amqpTemplate;


    @Override
    public List<SpecParamDTO> findSpuAllParamBySpuId(Long spuId, Boolean searching) {
        // 根据spuId查询categoryId，通过categoryId找到SpecParam信息
        Long categoryId = getById(spuId).getCid3();
        List<SpecParam> specParams = specParamService.query()
                .eq("category_id", categoryId)
                .eq(searching != null, "searching", searching)
                .list();
        // 转成DTO
        List<SpecParamDTO> specParamDTOS = SpecParamDTO.convertEntityList(specParams);

        // 查询json参数字符串
        String specification = spuDetailService.getById(spuId).getSpecification();
        // 转成集合形式
        Map<Long, Object> mapParam = JsonUtils.nativeRead(specification, new TypeReference<Map<Long, Object>>() {
        });

        // 遍历集合添加属性值---value数据
        specParamDTOS.forEach(specParamDTO -> {
            specParamDTO.setValue(mapParam.get(specParamDTO.getId()));
        });

        return specParamDTOS;
    }

    @Override
    public PageDTO<SpuDTO> findSpuByPage(Long brandId, Long categoryId, Long spuId, Integer page, Integer rows, Boolean saleable) {
        IPage<Spu> iPage = new Page<>(page, rows);
        page(iPage, new QueryWrapper<Spu>()
                .eq(brandId != null, "brand_id", brandId)
                .eq(categoryId != null, "cid3", categoryId)
                .eq(spuId != null, "id", spuId)
                .eq(saleable != null, "saleable", saleable)
        );
        List<SpuDTO> spuDTOS = SpuDTO.convertEntityList(iPage.getRecords());
        spuDTOS.forEach(spuDTO -> {
            spuDTO.setBrandName(brandService.getById(spuDTO.getBrandId()).getName());
            spuDTO.setCategoryName(categoryService.listByIds(spuDTO.getCategoryIds())
                    .stream().map(Category::getName)
                    .collect(Collectors.joining("/"))
            );
        });
        return new PageDTO<SpuDTO>(iPage.getTotal(), iPage.getPages(), spuDTOS);
    }

    @Override
    public SpuDTO findSpuAllBySpuId(Long spuId) {

        SpuDTO spuDTO = findSpuBySpuId(spuId);
        spuDTO.setSpuDetail(spuDetailService.findSpuDetailBySpuId(spuId));
        spuDTO.setSkus(skuService.findSkuBySpuId(spuId));

        return spuDTO;
    }

    @Override
    public SpuDTO findSpuBySpuId(Long spuId) {
        return new SpuDTO(getById(spuId));
    }

//    @Override
//    @Transactional
//    public void addOrUpdateSpu(SpuDTO spuDTO) {
//        Long spuId;
//        // 增加商品sku不能为空【健壮性判断】
//        if (EmptyUtil.isNullOrEmpty(spuId = spuDTO.getId())
//                && EmptyUtil.isNullOrEmpty(spuDTO.getSkus())) {
//            throw new YqException(400, "请至少添加一个sku");
//        }
//        System.out.println("spuId = " + spuId);
//
//        // 进行修改增加操作
//        boolean flag;
//        Spu spu = spuDTO.toEntity(Spu.class);
//        System.out.println("spu = " + spu);
//        System.out.println(!EmptyUtil.isAllFieldNull(spu));
//        if (!EmptyUtil.isAllFieldNull(spu)) {
//            flag = saveOrUpdate(spu);
//            if (!flag) {
//                throw new YqException(500, "添加/修改SPU异常");
//            }
//        }
//
//        List<SkuDTO> skuDTOS = spuDTO.getSkus();
//        if (!EmptyUtil.isNullOrEmpty(skuDTOS)) {
//            List<Sku> skus = skuDTOS.stream().map(skuDTO -> {
////                skuDTO.setSpuId(spuId);
//                return skuDTO.toEntity(Sku.class);
//            }).collect(Collectors.toList());
//            System.out.println("skus = " + skus);
//            flag = skuService.saveOrUpdateBatch(skus);
//            if (!flag) {
//                throw new YqException(500, "添加/修改SKU异常");
//            }
//        }
//
//        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
//        if (!EmptyUtil.isNullOrEmpty(spuDetailDTO)) {
//            SpuDetail spuDetail = spuDetailDTO.toEntity(SpuDetail.class);
////            spuDetail.setSpuId(spuId);
//            System.out.println("spuDetail = " + spuDetail);
//            flag = spuDetailService.saveOrUpdate(spuDetail);
//            if (!flag) {
//                throw new YqException(500, "添加/修改SPUDetail异常");
//            }
//        }
//
//    }

    @Override
    @Transactional
    public void updateSpuSaleable(Long spuId, Boolean saleable) {
        boolean flag = update(new UpdateWrapper<Spu>()
                .eq(spuId != null, "id", spuId)
                .set(saleable != null, "saleable", saleable));
        if (!flag) {
            throw new YqException(500, "上下架商品失败！");
        }
        flag = skuService.update(new UpdateWrapper<Sku>()
                .eq(spuId != null, "spu_id", spuId)
                .set(saleable != null, "saleable", saleable));
        if (!flag) {
            throw new YqException(500, "上下架商品失败！");
        }

        // 数据库下架发送消息通知ES索引库删除数据

        // 设置routingKey发送消息
        String routingKey = saleable ? MQConstants.RoutingKeyConstants.ITEM_UP_KEY : MQConstants.RoutingKeyConstants.ITEM_DOWN_KEY;

        // 使用amqp监听消息（指定交换机名称、指定routingKey，指定发送的消息）
        amqpTemplate.convertAndSend(MQConstants.ExchangeConstants.ITEM_EXCHANGE_NAME,routingKey,spuId);

    }

    @Override
    @Transactional
    public void addSpu(SpuDTO spuDTO) {
        // 增加商品sku不能为空【健壮性判断】
        List<SkuDTO> skuDTOS;
        if (EmptyUtil.isNullOrEmpty(skuDTOS = spuDTO.getSkus())) {
            throw new YqException(400, "请至少添加一个sku");
        }

        boolean flag;
        // 添加spu
        Spu spu = spuDTO.toEntity(Spu.class);
        System.out.println("spu = " + spu);
        flag = save(spu);
        if (!flag) {
            throw new YqException(500, "添加SPU异常");
        }

        Long spuId = spu.getId();

        // 添加spudetail
        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        SpuDetail spuDetail = spuDetailDTO.toEntity(SpuDetail.class);
        spuDetail.setSpuId(spuId);
        System.out.println("spuDetail = " + spuDetail);
        flag = spuDetailService.save(spuDetail);
        if (!flag) {
            throw new YqException(500, "添加SPUDetail异常");
        }

        // 添加sku
        List<Sku> skus = skuDTOS.stream().map(skuDTO -> {
            skuDTO.setSpuId(spuId);
            return skuDTO.toEntity(Sku.class);
        }).collect(Collectors.toList());
        System.out.println("skus = " + skus);
        flag = skuService.saveBatch(skus);
        if (!flag) {
            throw new YqException(500, "添加/修改SKU异常");
        }
    }

    @Override
    @Transactional
    public void updateSpu(SpuDTO spuDTO) {
        boolean flag;

        // 记录spuid判断是否修改
        Long spuId = spuDTO.getId();


        // 修改spu
        Spu spu;
        if (!EmptyUtil.isAllFieldNull(spu = spuDTO.toEntity(Spu.class))) {
            System.out.println("spu = " + spu);

            spuId = spu.getId();

            flag = updateById(spu);
            if (!flag) {
                throw new YqException(500, "修改SPU异常");
            }
        }

//        // 修改sku标题


        // 修改spuDetail
        SpuDetailDTO spuDetail;
        if (!EmptyUtil.isNullOrEmpty(spuDetail = spuDTO.getSpuDetail())) {
            spuId = spuDetail.getSpuId();

            System.out.println("spuDetail = " + spuDetail);
            flag = spuDetailService.updateById(spuDetail.toEntity(SpuDetail.class));
        }

        /*
            sku修改的三种情况：
                1. 普通属性修改【价格、库存、图片】saleable=null
                2. 新增sku【detail中增加特有选项】saleable=null
                3. 不启用【saleable=false】 --->  删除sku
         */

        // 修改sku
        List<SkuDTO> skuDTOS;
        List<Sku> removeSku = null;
        List<Sku> saveOrUpdateSku;
        if (!CollectionUtils.isEmpty(skuDTOS = spuDTO.getSkus())) {
            spuId = skuDTOS.get(0).getSpuId();


            // 按是否存在saleable分组，key=true ---> 普通修改/新增，key=false ---> 删除【最多两组】
            Map<Boolean, List<Sku>> map = skuDTOS.stream()
                    .map(skuDTO -> skuDTO.toEntity(Sku.class))
                    .collect(Collectors.groupingBy(sku -> sku.getSaleable() == null));

            if (!CollectionUtils.isEmpty(removeSku = map.get(false))) {
                // 删除sku
                skuService.removeByIds(removeSku.stream().map(Sku::getId).collect(Collectors.toList()));
            }

            if (!CollectionUtils.isEmpty(saveOrUpdateSku = map.get(true))) {
//                for (Sku sku : saveOrUpdateSku) {
//                    String newJSONString;
//                    if (!EmptyUtil.isNullOrEmpty(sku.getSpecialSpec())) {
//                        newJSONString = sku.getSpecialSpec();
//                    } else {
//                        newJSONString = skuService.getById(sku.getId()).getSpecialSpec();
//                    }
//
//                    Map<Long, String> newJSONMap = JsonUtils.nativeRead(newJSONString, new TypeReference<Map<Long, String>>() {
//                    });
//
//                    String newTitle = null;
//
//                    // 获取当前的spu-name
//                    SpuDTO oldSpuDTO = findSpuBySpuId(spuId);
//                    String newName = EmptyUtil.isNullOrEmpty(spuDTO.getName()) ? oldSpuDTO.getName() : spuDTO.getName();
//
//                    String newSkuTitle = newName + " " + StringUtils.join(newJSONMap.values(), " ");
//                    sku.setTitle(newSkuTitle);
//                }

                // 普通修改或者增加

                skuService.saveOrUpdateBatch(saveOrUpdateSku);
            }
        }


        // 修改sku标题 name + 特有属性
//        String newName;
//        String newValue;
//        newName = spuDTO.getName() == null ? findSpuBySpuId(spuId).getName() : spuDTO.getName();
//        String newJSONString;
//        if (skuDTOS != null) {
//            for (SkuDTO skuDTO : skuDTOS) {
//                if (skuDTO.getSpecialSpec() != null) {
//                    newJSONString = skuDTO.getSpecialSpec();
//                } else {
//                    newJSONString = skuService.getById(skuDTO.getId()).getSpecialSpec();
//                }
//                Map<Long, String> newJSONMap = JsonUtils.nativeRead(newJSONString, new TypeReference<Map<Long, String>>() {
//                });
//
//
//            }
//        }

    }



}
